﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LitJson;

namespace ZGameFramework.Setting
{

    public interface ITypeMemory
    {
        bool Load();

        bool Save();
    }

    public class TypeMemory<T>: ITypeMemory
    {
        internal class TypeMemoryData
        {
            public Dictionary<string, T> m_dictData = new Dictionary<string, T>();
        }

        public string Key = string.Empty;
        private TypeMemoryData TypeData;
        private bool IsAlter = false;

        public TypeMemory()
        {
            Key = "Setting_" + typeof(T).ToString();
        }

        /// <summary>
        /// 加载
        /// </summary>
        /// <returns></returns>
        public bool Load()
        {
            string strValue = PlayerPrefs.GetString( Key, string.Empty );
            if (!string.IsNullOrEmpty(strValue))
            {
                TypeData = JsonMapper.ToObject<TypeMemoryData>( strValue );
            }
            else
            {
                TypeData = new TypeMemoryData();
            }
            IsAlter = false;
            return true;
        }

        /// <summary>
        /// 保存数据
        /// </summary>
        /// <returns></returns>
        public bool Save()
        {
            if (!IsAlter) { return false; }

            string strValue = JsonMapper.ToJson(TypeData);
            PlayerPrefs.SetString(Key, strValue);
            IsAlter = false;
            return true;
        }

        /// <summary>
        /// 设置数据
        /// </summary>
        /// <param name="settingName"></param>
        /// <param name="settingValue"></param>
        public void SetValue( string settingName, T settingValue)
        {
            if (TypeData.m_dictData.ContainsKey(settingName))
            {
                TypeData.m_dictData[settingName] = settingValue;
            }
            else
            {
                TypeData.m_dictData.Add( settingName, settingValue );
            }
            IsAlter = true;
        }

        /// <summary>
        /// 获取数据
        /// </summary>
        /// <param name="settingName"></param>
        /// <returns></returns>
        public T GetValue( string settingName )
        { 
            if (TypeData.m_dictData.ContainsKey(settingName))
            {
                return TypeData.m_dictData[settingName];
            }   
            return default(T);
        }

        /// <summary>
        /// 获取数据
        /// 带缺省
        /// </summary>
        /// <param name="settingName"></param>
        /// <param name="settingValue"></param>
        /// <returns></returns>
        public T GetValue(string settingName, T settingDefault)
        {
            if (TypeData.m_dictData.ContainsKey(settingName))
            {
                return TypeData.m_dictData[settingName];
            }
            return settingDefault;
        }
    }

   
    public class SettingMemory : ISettingMemory
    {
        TypeMemory<bool> m_BoolMemory                  = new TypeMemory<bool>();
        TypeMemory<int> m_IntMemory                    = new TypeMemory<int>();
        TypeMemory<float> m_FloatMemory                = new TypeMemory<float>();
        TypeMemory<string> m_StringMemory              = new TypeMemory<string>();

        Dictionary<string, Setting.ITypeMemory> m_dictObjects = new Dictionary<string, Setting.ITypeMemory>();

        /// <summary>
        /// 加载数据
        /// </summary>
        public bool Load()
        {
            m_BoolMemory.Load();
            m_IntMemory.Load();
            m_FloatMemory.Load();
            m_StringMemory.Load();
            return true;
        }

        /// <summary>
        /// 保存数据
        /// </summary>
        public bool Save()
        {
            m_BoolMemory.Save();
            m_IntMemory.Save();
            m_FloatMemory.Save();
            m_StringMemory.Save();
            foreach (var val in m_dictObjects.Values) { val.Save(); }
            return true;
        }


        /// <summary>
        /// 获取数据
        /// </summary>
        /// <param name="settingName"></param>
        /// <returns></returns>
        public bool GetBool(string settingName)
        {
            return m_BoolMemory.GetValue( settingName );
        }

        /// <summary>
        /// 获取数据
        /// 带缺省
        /// </summary>
        /// <param name="settingName"></param>
        /// <param name="settingDefault"></param>
        /// <returns></returns>
        public bool GetBool(string settingName, bool settingDefault)
        {
            return m_BoolMemory.GetValue(settingName, settingDefault);
        }

        /// <summary>
        /// 设置数据
        /// </summary>
        /// <param name="settingName"></param>
        /// <param name="settingValue"></param>
        public void SetBool(string settingName, bool settingValue)
        {
            m_BoolMemory.SetValue(settingName, settingValue);
        }

        /// <summary>
        /// 获取数据 Int
        /// </summary>
        /// <param name="settingName"></param>
        /// <returns></returns>
        public int GetInt(string settingName)
        {
            return m_IntMemory.GetValue( settingName );
        }

        /// <summary>
        ///  获取数据 Int 
        ///  带默认值
        /// </summary>
        /// <param name="settingName"></param>
        /// <param name="settingDefault"></param>
        /// <returns></returns>
        public int GetInt(string settingName, int settingDefault)
        {
            return m_IntMemory.GetValue(settingName, settingDefault);
        }

        /// <summary>
        /// 设置数据 Int
        /// </summary>
        /// <param name="settingName"></param>
        /// <param name="settingValue"></param>
        public void SetInt(string settingName, int settingValue)
        {
            m_IntMemory.SetValue(settingName, settingValue);
        }

        /// <summary>
        /// 获取数据 
        /// </summary>
        /// <param name="settingName"></param>
        /// <returns></returns>
        public float GetFloat(string settingName)
        {
            return m_FloatMemory.GetValue(settingName);
        }

        /// <summary>
        /// 获取数据 
        /// 带缺省
        /// </summary>
        /// <param name="settingName"></param>
        /// <param name="settingDefault"></param>
        /// <returns></returns>
        public float GetFloat(string settingName, float settingDefault)
        {
            return m_FloatMemory.GetValue( settingName, settingDefault );
        }

        /// <summary>
        /// 设置参数
        /// </summary>
        /// <param name="settingName"></param>
        /// <param name="settingValue"></param>
        public void SetFloat(string settingName, float settingValue)
        {
            m_FloatMemory.SetValue( settingName, settingValue);
        }

        /// <summary>
        /// 获取数据
        /// </summary>
        /// <param name="settingName"></param>
        /// <returns></returns>
        public string GetString(string settingName)
        {
            return m_StringMemory.GetValue( settingName);
        }

        /// <summary>
        /// 获取数据 
        /// 带缺省
        /// </summary>
        /// <param name="settingName"></param>
        /// <param name="settingDefault"></param>
        /// <returns></returns>
        public string GetString(string settingName, string settingDefault)
        {
            return m_StringMemory.GetValue( settingName, settingDefault );
        }

        /// <summary>
        ///  设置数据
        /// </summary>
        /// <param name="settingName"></param>
        /// <param name="settingValue"></param>
        public void SetString(string settingName, string settingValue)
        {
            m_StringMemory.SetValue( settingName, settingValue);
        }

        /// <summary>
        /// 获取数据
        /// </summary>
        /// <param name="settingName"></param>
        /// <returns></returns>
        public T GetObject<T>(string settingName)
        {
            TypeMemory<T> obj_typeMemory = GetTypeMemory<T>();
            return obj_typeMemory.GetValue(settingName);
        }

        /// <summary>
        /// 获取数据
        /// 带缺省
        /// </summary>
        /// <param name="settingName"></param>
        /// <param name="settingDefault"></param>
        /// <returns></returns>
        public T GetObject<T>(string settingName, T settingDefault)
        {
            TypeMemory<T> obj_typeMemory = GetTypeMemory<T>();
            return obj_typeMemory.GetValue(settingName, settingDefault);
        }

        /// <summary>
        /// 设置数据
        /// </summary>
        /// <param name="settingName"></param>
        /// <param name="settingValue"></param>
        public void SetObject<T>(string settingName, T settingValue)
        {
            TypeMemory<T> obj_typeMemory = GetTypeMemory<T>();
            obj_typeMemory.SetValue(settingName, settingValue);
        }


        /// <summary>
        /// 加载类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        private TypeMemory<T> GetTypeMemory<T>()
        {
            string typeName = typeof(T).ToString();
            ITypeMemory typeMemory = null;
            TypeMemory<T> obj_typeMemory = null;
            if (m_dictObjects.TryGetValue(typeName, out typeMemory))
            {
                obj_typeMemory = typeMemory as TypeMemory<T>;
            }
            if (null == obj_typeMemory)
            {
                obj_typeMemory = new TypeMemory<T>();
                obj_typeMemory.Load();
                m_dictObjects.Add(typeName, obj_typeMemory);
            }
            return obj_typeMemory;
        }

       
    }
}